package com.googlecode.afx.tools.template;

import java.io.FileWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.FieldCallback;

/**
 * Generates table views for Java class files.
 * 
 * @author Martin
 *
 */
public class TableViewGenerator {

	private static class FieldNameExtractor implements FieldCallback {

		private List<String> fieldList = new ArrayList<String>();

		private BeanWrapper wrapper;

		public FieldNameExtractor(Class<?> clazz) {
			wrapper = new BeanWrapperImpl(clazz);
		}

		@Override
		public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
			Class<?> type = field.getType();
			if (wrapper.isReadableProperty(field.getName())) {
				if (type.isAssignableFrom(String.class) || 
 					type.isAssignableFrom(Integer.class)	||
 					type.isAssignableFrom(Float.class)	||
 					type.isAssignableFrom(Double.class)	||
 					type.isAssignableFrom(Boolean.class)	||
 					type.isAssignableFrom(Long.class)	) {
					
					fieldList.add(field.getName());
				}
			}
		}

		public List<String> getFieldList() {
			return fieldList;
		}

	}

	public static Class<?> loadClass(String classFile) throws Exception {
		ClassLoader loader = TableViewGenerator.class.getClassLoader();
		Class<?> clazz = loader.loadClass(classFile);
		return clazz;
	}

	public static List<String> extractFields(Class<?> clazz) {
		FieldNameExtractor extractor = new FieldNameExtractor(clazz);
		ReflectionUtils.doWithFields(clazz, extractor);
		return extractor.getFieldList();
	}
	
	public static void generateFxml(String output, List<String> fields) throws Exception {
		FileWriter writer = new FileWriter(output);
		
		StringBuilder b = new StringBuilder();
		
		b.append("<TableView prefHeight=\"-1.0\" prefWidth=\"-1.0\">").append("\n");
		b.append("  <columns>").append("\n");
		for(String field : fields) {
			b.append("		<TableColumn prefWidth=\"-1\" text=\"").append(splitCamelCase(field)).append("\">").append("\n");
			b.append("          <cellValueFactory><PropertyValueFactory property=\"").append(field).append("\" /></cellValueFactory>").append("\n");
			b.append("		</TableColumn>").append("\n");
		}
		b.append("  </columns>").append("\n");
		b.append("</TableView>").append("\n");
		
		writer.write(b.toString());
		
		writer.close();
	}

	public static String splitCamelCase(String s) {
		   return s.replaceAll(
		      String.format("%s|%s|%s",
		         "(?<=[A-Z])(?=[A-Z][a-z])",
		         "(?<=[^A-Z])(?=[A-Z])",
		         "(?<=[A-Za-z])(?=[^A-Za-z])"
		      ),
		      " "
		   );
		}	
	
	public static final void main(String[] args) throws Exception {
		if (args == null || args.length != 2) {
			System.out.println("Usage: java TableViewGenerator <class-file> <fxml-output-file>");
			System.exit(0);
		}
		String input = args[0];
		String output = args[1];
		
		Class<?> clazz = loadClass(input);
		List<String> fields = extractFields(clazz);
		generateFxml(output, fields);
	}

}
